//go:build wireinject
// +build wireinject

package wire

import (
	"context"
	"github.com/starmotioncf/common/app"
	"github.com/starmotioncf/common/db"
	"github.com/starmotioncf/common/event/event_bus"
	"github.com/starmotioncf/common/log"
	"github.com/starmotioncf/common/openapi"
	"github.com/starmotioncf/common/redis"
	"github.com/starmotioncf/common/server/http"
	"github.com/starmotioncf/common/server/pprof"
	"github.com/starmotioncf/soutchatinternal/handler"
	"github.com/starmotioncf/soutchatinternal/middleware"
	"github.com/starmotioncf/soutchatinternal/repository"
	implRepo "github.com/starmotioncf/soutchatinternal/repository/impl"
	"github.com/starmotioncf/soutchatinternal/router"
	"github.com/starmotioncf/soutchatinternal/server"
	"github.com/starmotioncf/soutchatinternal/service"
	implSvr "github.com/starmotioncf/soutchatinternal/service/impl"
	"github.com/starmotioncf/soutchatpkg/account"
	"github.com/starmotioncf/soutchatpkg/jwt"
	"github.com/starmotioncf/soutchatpkg/notify"
	"github.com/starmotioncf/soutchatpkg/sms"
	"github.com/starmotioncf/soutchatpkg/storage"

	"github.com/google/wire"
)

var pkgSet = wire.NewSet(
	log.NewLog,
	db.NewMsDB,
	redis.NewRedis,
	redis.NewRateLimit,
	event_bus.NewEventBus,

	account.NewAccountAuth,
	jwt.NewJwt,
	notify.NewNotify,
	sms.NewSms,
	storage.NewStorage,
)

var repositorySet = wire.NewSet(
	repository.NewRepository,
	repository.NewTransaction,
	implRepo.NewAccountRepository,
	implRepo.NewThirdGameRepository,
	implRepo.NewCountryRepository,
	implRepo.NewRestrictionRepository,
	implRepo.NewSettingRepository,
	implRepo.NewUserRepository,
	implRepo.NewUserIdRepository,
	implRepo.NewOrderRepository,
	implRepo.NewLangRepository,
	implRepo.NewCaptchaRepository,
)

var serviceSet = wire.NewSet(
	service.NewService,
	implSvr.NewCommonService,
	implSvr.NewAccountService,
	implSvr.NewPaymentService,
	implSvr.NewThirdGameService,
	implSvr.NewRestrictionService,
	implSvr.NewSettingService,
	implSvr.NewSmsService,
	implSvr.NewCountryService,
)

var handlerSet = wire.NewSet(
	handler.NewHandler,
	handler.NewIndexHandler,
	handler.NewAccountHandler,
	handler.NewPaymentHandler,
	handler.NewThirdGameHandler,
	handler.NewCountryHandler,
	handler.NewSmsHandler,
)

var routerSet = wire.NewSet(
	router.NewOpenapiRouter,
	router.NewMustLoginRouter,
	router.NewWithoutLoginRouter,
	router.NewThirdCallbackRouter,
)

var middlewareSet = wire.NewSet(
	middleware.NewAuthMiddleware,
	middleware.NewOpenapiMiddleware,
	middleware.NewRateLimitMiddleware,
	middleware.NewFilterEntityMiddleware,
	middleware.NewMaskChinaMiddleware,
	middleware.NewRestrictionMiddleware,
)

var serverSet = wire.NewSet(
	server.NewHTTPServer,
	server.NewPProfServer,
)

// build App
func newApp(httpServer *http.Server, pprof *pprof.Server) *app.App {
	return app.NewApp(
		app.WithServer(httpServer, pprof),
		app.WithName("soutchat-server"),
	)
}

func NewApp(
	ctx context.Context,
	logConf log.Config,
	dbConf db.MsConfig,
	rdbConf redis.Config,
	jwtConf jwt.Config,
	openapiConf openapi.Config,
	rateLimitConf redis.RateLimiterConfig,
	pprofConf pprof.Config,
	httpConf http.Config,
	paymentConf service.PaymentConfig,
	storageConf storage.Config,
	accountConf account.Config,
	thirdGameConf service.ThirdGameConfig,
	notifyConfig notify.Config,
	smsConfig sms.Config,
) (*app.App, func(), error) {
	panic(wire.Build(
		pkgSet,
		repositorySet,
		serviceSet,
		handlerSet,
		routerSet,
		middlewareSet,
		serverSet,
		newApp,
	))
}
